package com.franklin.java.api.psi.comment;

import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.Nullable;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * @author Franklin
 * @since 2021/9/2 14:42
 */
public class PsiCommentResolverFactory implements PsiCommentResolver<PsiElement> {

    protected Map<Class<?>,PsiCommentResolver<? extends PsiElement>> typeResolverMap = new HashMap<>();

    private static PsiCommentResolverFactory INSTANCE = new PsiCommentResolverFactory();

    public PsiCommentResolverFactory() {
        PsiFieldCommentResolver psiFieldCommentResolver = new PsiFieldCommentResolver();
        PsiMethodCommentResolver psiMethodCommentResolver = new PsiMethodCommentResolver();
        PsiClassCommentResolver psiClassCommentResolver = new PsiClassCommentResolver();

        typeResolverMap.put(psiFieldCommentResolver.getClazz(),psiFieldCommentResolver);
        typeResolverMap.put(psiMethodCommentResolver.getClazz(),psiMethodCommentResolver);
        typeResolverMap.put(psiClassCommentResolver.getClazz(),psiClassCommentResolver);
    }

    public static PsiCommentResolverFactory getInstance() {
        return INSTANCE;
    }

    @Nullable
    private PsiCommentResolver<PsiElement> getResolver(PsiElement psiElement) {
        Class<? extends PsiElement> aClass = psiElement.getClass();
        for (Map.Entry<Class<?>, PsiCommentResolver<? extends PsiElement>> entry : typeResolverMap.entrySet()) {
            if (entry.getKey().isAssignableFrom(aClass)){
                return (PsiCommentResolver<PsiElement>) entry.getValue();
            }
        }
        return null;
    }

    @Override
    public String resolveComment(PsiElement psiElement) {
        return Optional.ofNullable(getResolver(psiElement))
                .map(psiCommentResolver -> psiCommentResolver.resolveComment(psiElement))
                .orElse("");
    }

    @Override
    public String resolveSimpleComment(PsiElement psiElement) {
        return Optional.ofNullable(getResolver(psiElement))
                .map(psiCommentResolver -> psiCommentResolver.resolveSimpleComment(psiElement))
                .orElse("");
    }
}
